<%@ Page Language="C#"%>
<%@ Import namespace="SubSonic.Utilities"%>
<%@ Import Namespace="SubSonic" %>
<%
    string providerName = "#PROVIDER#";
    string viewName = "#VIEW#";
    //The data we need
    TableSchema.Table view = DataService.GetSchema(viewName, providerName, TableType.View);
    LanguageType lang = LanguageType.CSharp;
    
    //The main vars we need
    TableSchema.TableColumnCollection cols = view.Columns;
    string className = view.ClassName;
    string nSpace = DataService.Providers[providerName].GeneratedNamespace;

    
%>
namespace <%=nSpace %>{

    
    /// <summary>
    /// This is  Read-only wrapper class for the <%=viewName%> view.
    /// </summary>
    [Serializable]
    public partial class <%=className%> : ReadOnlyRecord[<]<%= className %>[>] 
    {
    
	    #region Default Settings
        /// <summary>
        /// Retrieve the schema for this table
        /// </summary>	   	    
	    protected static void SetSQLProps() 
	    {
		    GetTableSchema();
	    }
	    #endregion

        #region Schema Accessor
        /// <summary>
        /// Gets the schema that describes the persistance of this object
        /// </summary>            
	    public static TableSchema.Table Schema
        {
            get
            {
                if (BaseSchema == null)
                {
                    SetSQLProps();
                }
                return BaseSchema;
            }
        }
    	
        private static void GetTableSchema() 
        {
            if(!IsSchemaInitialized)
            {
                //Schema declaration
                TableSchema.Table schema = new TableSchema.Table("<%=viewName%>", TableType.View, DataService.Provider);
                schema.Columns = new TableSchema.TableColumnCollection();
                schema.SchemaName = "<%=view.SchemaName%>";

                //columns
                <%
                foreach(TableSchema.TableColumn col in cols)
				{
                    string varName = "col" + col.ArgumentName;
                %>
                TableSchema.TableColumn <%=varName %> = new TableSchema.TableColumn(schema);
                <%=varName %>.ColumnName = "<%= col.ColumnName %>";
                <%=varName %>.DataType = DbType.<%=col.DataType %>;
                <%=varName %>.MaxLength = <%=col.MaxLength %>;
                <%=varName %>.AutoIncrement = false;
                <%=varName %>.IsNullable = <%=col.IsNullable.ToString().ToLower()%>;
                <%=varName %>.IsPrimaryKey = false;
                <%=varName %>.IsForeignKey = false;
                <%=varName %>.IsReadOnly = <%= col.IsReadOnly.ToString().ToLower() %>;
                <%
				if(col.IsForeignKey)
				{
                %>
				<%=varName %>.ForeignKeyTableName = "<%= col.ForeignKeyTableName %>";
                <% } %>
                schema.Columns.Add(<%=varName%>);

                <%
                }
                %>
                
                BaseSchema = schema;
                //add this schema to the provider
                //so we can query it later
                DataService.Provider.AddSchema("<%=viewName%>",schema);
            }
        }
        #endregion
        
        #region Query Accessor
        /// <summary>
        /// Generates a new query based on the schema of this object
        /// </summary>                
	    public static Query CreateQuery()
	    {
		    return new Query(Schema);
	    }
	    #endregion
	    
	    #region .ctors
        /// <summary>
        /// default constructor
        /// </summary>		    	    
	    public <%=className %>()
	    {
            SetSQLProps();
            SetDefaults();
            MarkNew();
        }

        /// <summary>
        /// loads a new object with the given key
        /// </summary>
	    public <%=className %>(object keyID)
	    {
		    SetSQLProps();
		    LoadByKey(keyID);
	    }
    	 
        /// <summary>
        /// loads a new object with the given value in the given field
        /// </summary>
	    public <%=className %>(string columnName, object columnValue)
        {
            SetSQLProps();
            LoadByParam(columnName,columnValue);
        }
        
	    #endregion
	    
	    #region Props
	    
        <%
        foreach(TableSchema.TableColumn col in cols){
            string propName = col.PropertyName;
            string varType = Utility.GetVariableType(col.DataType, col.IsNullable, lang);
        %>  
        /// <summary>
        /// Gets and Sets the value for <%= propName %>
        /// </summary>        
        [XmlAttribute("<%=propName%>")]
        public <%=varType%> <%=propName%> 
	    {
		    get
		    {
			    return GetColumnValue[<]<%= varType %>[>]("<%=propName%>");
		    }
            set 
		    {
			    MarkDirty();
			    SetColumnValue("<%=propName%>", value);

            }
        }
	    <%
	    }
	    %>
	    #endregion
    
	    #region Columns Struct
        /// <summary>
        /// List of columns/properties available in this object
        /// </summary>	
	    public struct Columns
	    {
		    
		    <% 
		    foreach (TableSchema.TableColumn col in cols) {
                string propName = col.PropertyName;
            %>
            /// <summary>
            /// <%= propName %>
            /// </summary>            
            public static string <%=propName%>  = @"<%=propName%>";
            <%
              } 
            %>

	    }
	    #endregion
    }
 
    #region <%=className %>Collection
    /// <summary>
    /// Strongly-typed collection for the <%=className%> class.
    /// </summary>

    [Serializable]
    public partial class <%=className%>Collection : ReadOnlyList[<]<%= className %>[>]
    {
        List[<]Where[>] wheres = new List[<]Where[>]();
        List[<]BetweenAnd[>] betweens = new List[<]BetweenAnd[>]();
        SubSonic.OrderBy orderBy;
    	
        /// <summary>
        /// returns this collection ordered ascending by the given column
        /// </summary>    	    	
        public <%=className%>Collection OrderByAsc(string columnName) 
        {
            this.orderBy = SubSonic.OrderBy.Asc(columnName);
            return this;
        }
    	
        /// <summary>
        /// returns this collection ordered descending by the given column
        /// </summary>
        public <%=className%>Collection OrderByDesc(string columnName) 
        {
            this.orderBy = SubSonic.OrderBy.Desc(columnName);
            return this;
        }

        /// <summary>
        /// returns this collection constrained to dates in the given column between the given values
        /// </summary>
        public <%=className%>Collection WhereDatesBetween(string columnName, DateTime dateStart, DateTime dateEnd) 
        {
            return BetweenAnd(columnName, dateStart, dateEnd);
        }

        /// <summary>
        /// append the given where clause to contrain this collection
        /// </summary>
        public <%=className%>Collection Where(Where where) 
        {
            wheres.Add(where);
            return this;
        }
    	
        /// <summary>
        /// returns this collection with the given field/value pair added to the where clause 
        /// </summary>
        public <%=className%>Collection Where(string columnName, object value) 
        {
            if(value != DBNull.Value && value != null)
            {	
                return Where(columnName, Comparison.Equals, value);
            }
            else
            {
                return Where(columnName, Comparison.Is, DBNull.Value);
            }
        }
    	
        /// <summary>
        /// returns this collection with the given field/value pair added to the where clause 
        /// </summary>
        public <%=className%>Collection Where(string columnName, Comparison comp, object value) 
	    {
            Where where = new Where();
            where.ColumnName = columnName;
            where.Comparison = comp;
            where.ParameterValue = value;
            Where(where);
            return this;
        }
    	
        /// <summary>
        /// returns this collection constrained to dates in the given column between the given values
        /// </summary>
        public <%=className%>Collection BetweenAnd(string columnName, DateTime dateStart, DateTime dateEnd) 
	    {
            BetweenAnd between = new BetweenAnd();
            between.ColumnName = columnName;
            between.StartDate = dateStart;
            between.EndDate = dateEnd;
            between.StartParameterName = "start" + columnName; 
            between.EndParameterName = "end" + columnName; 
            betweens.Add(between);
            return this;
        }
    	
        /// <summary>
        /// loads data from the data store based on the where clause and order previously loaded into this object
        /// </summary>
        public <%=className%>Collection Load() 
	    {
            Query qry = new Query(<%=className%>.Schema);
            CheckLogicalDelete(qry);
            foreach (Where where in wheres) 
            {
                qry.AddWhere(where);
            }
             
            foreach (BetweenAnd between in betweens)
            {
                qry.AddBetweenAnd(between);
            }

            if (orderBy != null)
            {
                qry.OrderBy = orderBy;
            }

            IDataReader rdr = qry.ExecuteReader();
            this.Load(rdr);
            rdr.Close();
            return this;
        }
        
        /// <summary>
        /// default constructor
        /// </summary>
        public <%=className%>Collection() 
        {
            

        }
    }
    
    #endregion

    
}